package org.koron.ebs.util.field;

import java.util.LinkedHashMap;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.koron.ebs.util.Utils;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

public class FieldBeanProcessor {
	/**
	 * 栏位BEAN
	 */
//	private FieldBean bean;
	private static FieldBeanProcessor PROCESSOR ;
	static
	{
		String processor = System.getProperty("FieldBeanProcessor");
		if (processor != null) {
			try {
				PROCESSOR = (FieldBeanProcessor) Class.forName(processor).newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}
		}
		if(PROCESSOR==null)
			PROCESSOR = new FieldBeanProcessor();
	}
	/**
	 * 构造函数
	 * 
	 * @param bean 栏位BEAN
	 */
	protected FieldBeanProcessor() {
//		this.bean = bean;
	}

	/**
	 * 获取生成HTML块的实例
	 * 
	 * @param bean 要处理的BEAN
	 * @return 相应的HTML处理器
	 */
	public static final FieldBeanProcessor newInstance() {
		return PROCESSOR;
	}

	/**
	 * 用来生成html块
	 * @return html字符串
	 */
	public final String html(FieldBean bean,Object value) {
		if (bean == null)
			return "";
		FieldBean bean2 = bean.clone();
		if(bean2.getParam(FieldBean.BEANFILTER)!=null)
		{
			try {
				Class<?> tmp = Class.forName(bean2.getParam(FieldBean.BEANFILTER));
				if(FieldBeanFilter.class.isAssignableFrom(tmp))
				{
					bean2 = ((FieldBeanFilter)tmp.newInstance()).filter(bean2);
				}
			} catch (ClassNotFoundException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取bean过滤器出错"+e.getMessage());
			} catch (InstantiationException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取bean过滤器出错"+e.getMessage());
			} catch (IllegalAccessException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取bean过滤器出错"+e.getMessage());				
			}
		}
		HtmlTag input = null;
		if ((bean2.getType() & FieldBean.TEXTFIELD) != 0)// 文本框
		{
			input = textField(bean2,value);
		} else if ((bean2.getType() & FieldBean.SELECT) != 0)// 下拉框
		{
			input = select(bean2,value);
		} else if ((bean2.getType() & FieldBean.CHECKBOX) != 0)// 复选
		{
			input = checkbox(bean2,value);
		} else if ((bean2.getType() & FieldBean.RADIO) != 0)// 单选
		{
			input = radio(bean2,value);
		} else if ((bean2.getType() & FieldBean.TEXTAREA) != 0) {
			input = textarea(bean2,value);
		} else if ((bean2.getType() & FieldBean.BUTTON) != 0) {
			input = button(bean2,value);
		} else if ((bean2.getType() & FieldBean.LABEL) != 0) {
			input = label(bean2,value);
		} else if ((bean2.getType() & FieldBean.IMAGE) != 0) {
			input = image(bean2,value);
		}
		if(bean2.getParam(FieldBean.TAGFILTER)!=null)
		{
			try {
				Class<?> tmp = Class.forName(bean2.getParam(FieldBean.TAGFILTER));
				if(TagFilter.class.isAssignableFrom(tmp))
				{
					input = ((TagFilter)tmp.newInstance()).filter(input,bean2);
				}
			} catch (ClassNotFoundException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取tag过滤器出错"+e.getMessage());
			} catch (InstantiationException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取tag过滤器出错"+e.getMessage());
			} catch (IllegalAccessException e) {
				Logger.getLogger(FieldBeanProcessor.class).warn("获取tag过滤器出错"+e.getMessage());				
			}
		}
		if (input == null)
			return "";
		return input.html();
	}

	/**
	 * 生成图片标签
	 * 
	 * @return Html标签
	 */
	protected HtmlTag image(FieldBean bean,Object value) {
		HtmlTag input = new HtmlTag("img").attr("src", Utils.isNull(value,String.valueOf(value),""))
				.attr("name", bean.getName()).attr("alt", bean.getDesc()).addClass(bean.getClassName());
		HtmlTag div = new HtmlTag("div");
		div.append(new HtmlTag("label").append(new HtmlTag("", bean.getCaption())).append(input));
		return div;
	}

	/**
	 * 生成文本
	 * 
	 * @return Html标签
	 */
	protected HtmlTag label(FieldBean bean,Object value) {
		HtmlTag input = new HtmlTag("span").append(new HtmlTag("", bean.getDesc())).addClass(
				bean.getClassName());
		HtmlTag div = new HtmlTag("div");
		div.append(new HtmlTag("label").append(new HtmlTag("", bean.getCaption())).append(input));
		if((bean.getType() & FieldBean.LABEL_PEER) == FieldBean.LABEL_PEER)
		{
			input.setTag("div");
			input.css("width",bean.getParam("width"));
			return input;
		}
		return div;
	}

	/**
	 * 生成按钮
	 * 
	 * @return Html标签
	 */
	protected HtmlTag button(FieldBean bean,Object value) {
		HtmlTag input;
		input = new HtmlTag("input").attr("type", "button").attr("value", bean.getCaption())
				.attr("name", bean.getName()).addClass(bean.getClassName());
		HtmlTag div = new HtmlTag("div");
		div.append(new HtmlTag("label").append(new HtmlTag("", bean.getCaption())).append(input));
		return div;
	}

	/**
	 * 生成多栏文本框
	 * 
	 * @return Html标签
	 */
	protected HtmlTag textarea(FieldBean bean,Object value) {
		HtmlTag input;
		input = new HtmlTag("textarea").append(new HtmlTag("", Utils.isNull(value,String.valueOf(value),"")))
				.attr("name", bean.getName()).addClass(bean.getClassName());
		HtmlTag div = new HtmlTag("div");
		div.append(new HtmlTag("label").append(new HtmlTag("", bean.getCaption())).append(input));
		return div;
	}

	/**
	 * 生成单选框
	 * 
	 * @return Html标签
	 */
	protected HtmlTag radio(FieldBean bean,Object value) {
		return commonBox("radio",bean,value);
	}

	/**
	 * 生成复选
	 * 
	 * @return Html标签
	 */
	protected HtmlTag checkbox(FieldBean bean,Object value) {
		return commonBox("checkbox",bean,value);
	}

	/**
	 * 生成下拉框
	 * 
	 * @return Html标签
	 */
	protected HtmlTag select(FieldBean bean,Object value) {
		HtmlTag input;
		input = new HtmlTag("select");
		input.attr("name", bean.getName()).addClass(bean.getClassName());
		if ((bean.getType() & FieldBean.STATICDATA) != 0) {
			LinkedHashMap<String, String> map = new Gson().fromJson(bean.getParam("data"),
					new TypeToken<LinkedHashMap<String, String>>() {
					}.getType());
			String defaultValue = Utils.isNull(value,String.valueOf(value),"");
			for (Entry<String, String> entry : map.entrySet()) {
				HtmlTag option = new HtmlTag("option").attr("value", entry.getKey()).append(
						new HtmlTag("", entry.getValue()));
				if (entry.getKey().equals(defaultValue) || entry.getValue().equals(defaultValue))
					option.attr("selected", "selected");
				input.append(option);
			}
		}
		HtmlTag div = new HtmlTag("div");
		div.append(new HtmlTag("label").append(new HtmlTag("", bean.getCaption())).append(input));
		return div;
	}

	/**
	 * 生成单行文本框
	 * @return Html标签
	 */
	protected HtmlTag textField(FieldBean bean,Object value) {
		HtmlTag input = new HtmlTag("input");
		input.attr("type", "text").attr("name", bean.getName()).addClass(bean.getClassName());
		String defaultValue = Utils.isNull(value,String.valueOf(value),"");
		if (defaultValue != null)
			input.attr("value", defaultValue);
		String placeHolder = bean.getParam("placeholder");
		if (placeHolder != null)
			input.attr("placeholder", placeHolder);
		if ((bean.getType() & FieldBean.TEXTFIELD_PASSWORD) != 0) {
			input.attr("type", "password");
		}
		HtmlTag div = new HtmlTag("","").append(new HtmlTag("div").append(new HtmlTag("", bean.getCaption())));
		div.append(input);
		return div;
	}

	/**
	 * 生成单选框或复选框,被调用
	 * 
	 * @param type 类型,checkbox或radio
	 * @return Html标签
	 */
	protected HtmlTag commonBox(String type,FieldBean bean,Object value) {
		HtmlTag input = new HtmlTag("ul"); 
		new HtmlTag("","").append(new HtmlTag("div").append(new HtmlTag("",bean.getCaption())));
		
		if ((bean.getType() & FieldBean.STATICDATA) != 0) {
			LinkedHashMap<String, String> map = new Gson().fromJson(bean.getParam("data"),
					new TypeToken<LinkedHashMap<String, String>>() {
					}.getType());
			String defaultValue = Utils.isNull(value,String.valueOf(value),"");
			for (Entry<String, String> entry : map.entrySet()) {
				HtmlTag option = new HtmlTag("input").attr("value", entry.getKey()).attr("type", type)
						.attr("name", bean.getName()).addClass(bean.getClassName());
				if (entry.getKey().equals(defaultValue) || entry.getValue().equals(defaultValue))
					option.attr("checked", "checked");
				input.append(new HtmlTag("li").append(new HtmlTag("label").append(option).append(new HtmlTag("", entry.getValue()))));
			}
		}
		HtmlTag div = new HtmlTag("div").append(input);
		return div;
	}
}
